﻿#pragma once
#include "callback.h"
#include "config.h"
#include "hid_decoder.h"
#include "hid_encoder.h"
#include "hid_interface.h"
#include <memory>

/**
 * 等待ACK恢复超时时间，默认100毫秒
 */
#define ACK_RESPONSE_TIMEOUT 500

/**
 * HID 管理器，负责用户的所有交互逻辑
 * @brief The hid_engine class
 */
class hid_engine {

private:
  std::mutex g_Mutex;
  enum SendState { TEXT, FILE, RANDOM_FILE };
  SendState sendState = TEXT;

  // ack锁
  std::mutex ack_mutex_;

  // ack条件变量
  std::condition_variable ack_cv_;

  // 改为智能指针
  // 共享hid_interface实例
  std::shared_ptr<hid_interface> hidInterface;
  std::shared_ptr<config> cfg;
  std::shared_ptr<hid_encoder> encoder;
  std::shared_ptr<hid_decoder> decoder;

  std::weak_ptr<OnHIDFrameListener> mHIDFrameListener;
  std::weak_ptr<OnHIDWriteListener> mHIDWriteListener;
  std::weak_ptr<OnHIDWriteRandomFileListener> mHIDWriteRandomFileListener;

public:
  // 同步写数据
  bool writePingPong(const char *data, int size, const char *tag, int tagSize,
                     char cmd);

  // 同步写数据（内部调用）
  bool WriteACK(const char *data, int size, const char *tag, int tagSize,
                char cmd);

public:
  hid_engine(std::shared_ptr<hid_interface> _hid_interface,
             std::shared_ptr<config> _cfg);
  ~hid_engine();

  // 指定vid和pid打开设备
  int open(unsigned short vendor_id, unsigned product_id);

  // 关闭设备
  int close();

  // 释放
  int release();

  // 回复 Pong 数据
  void writePongData();

  // 同步写数据
  int writeDataSync(const char *data, int size, const char *tag, int tagSize,
                    char cmd);

  // 异步写数据，带回调函数
  void writeData(const char *data, int size, const char *tag, int tagSize,
                 char cmd, std::weak_ptr<OnHIDWriteListener> l);

  // 异步写文件
  void writeFile(const std::string &filePath, const char *tag, int tagSize,
                 std::weak_ptr<OnHIDWriteListener> l);

  // 同步写文件
  void writeFile(const std::string &filePath, const char *tag, int tagSize);

  // 写随机文件
  void writeRandomFile(const string &filePath, int fileExtension,
                       std::weak_ptr<OnHIDWriteRandomFileListener> l);

  // 取消随机写文件
  void cancelRandomFile();

  // 停止写随机文件
  void stopRandomFile();

  // 暂停任务
  void pause();

  // 恢复任务
  void resume();

  // 停止发送数据
  bool stop(std::weak_ptr<OnHIDStopDataListener> m_StopDataListener);

  // 获取当前文件路径
  std::string getDownloadFilePath() const;

  // 设置HID异常监听器
  void setOnHIDErrorListener(std::weak_ptr<OnHIDErrorListener> l);

  // 设置HID帧数据（文本）监听器
  void setOnHIDFrameListener(std::weak_ptr<OnHIDFrameListener> l);

  // 设置HID文件监听器
  void setOnHIDReadFileListener(std::weak_ptr<OnHIDReadFileListener> l);

  // 设置HID随机文件读写监听器
  void
  setOnHIDReadRandomFileListener(std::weak_ptr<OnHIDReadRandomFileListener> l);

  // 设置HID读随机文件监听器
  void
  setOnReadRandomFileListener(std::weak_ptr<OnHIDReadRandomFileListener> l);

  // 监听停止事件
  void setOnHIDStopListener(std::weak_ptr<OnHIDStopDataListener> l);
};
